import auth from "@/plugins/auth";
import router, { constantRoutes, dynamicRoutes } from "@/router";
import { teacher_constantRoutes } from "@/router/teacher";
import { student_constantRoutes } from "@/router/student";
import { library_Routes } from "@/router/library";
import user from "./user";
import { getRouters } from "@/api/menu";
import Layout from "@/layout/index";
import ParentView from "@/components/ParentView";
import InnerLink from "@/layout/components/InnerLink";
import Vue from "vue";
let filtersRouters;
let filterAddRouters;
const permission = {
  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],
    curRole: "",
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      let curRole = localStorage.getItem("curRole")
        ? localStorage.getItem("curRole")
        : user.state.roles[0];
      state.curRole = localStorage.getItem("curRole");
      state.addRoutes = routes;
      let baseRoutes;
      if (curRole == "teacher") {
        baseRoutes = teacher_constantRoutes;
        baseRoutes = [...baseRoutes, ...library_Routes]
      } else if (curRole == "student") {
        baseRoutes = student_constantRoutes;
      } else {
        baseRoutes = constantRoutes;
        baseRoutes = [...baseRoutes, ...library_Routes]
      }
      state.addRoutes = routes;
      state.routes = filtersRouters
        ? filtersRouters
        : baseRoutes.concat(routes);
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      let curRole = localStorage.getItem("curRole")
        ? localStorage.getItem("curRole")
        : user.state.roles[0];
      state.addRoutes = routes;
      let baseRoutes;
      if (curRole == "teacher") {
        baseRoutes = teacher_constantRoutes;
        baseRoutes = [...baseRoutes, ...library_Routes]
      } else if (curRole == "student") {
        baseRoutes = student_constantRoutes;
      } else {
        baseRoutes = constantRoutes;
        baseRoutes = [...baseRoutes, ...library_Routes]
      }
      state.defaultRoutes = baseRoutes.concat(routes);
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes;
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes;
    },
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }, view) {
      return new Promise(async (resolve) => {
        let curRole = localStorage.getItem("curRole")
          ? localStorage.getItem("curRole")
          : user.state.roles[0];
        console.log(
          "curRole",
          curRole,
          user.state.roles,
          localStorage.getItem("curRole")
        );
        let baseRoutes;
        if (curRole == "teacher" || curRole == "assistant" ) {
          baseRoutes = teacher_constantRoutes;
          baseRoutes = [...baseRoutes, ...library_Routes]
        } else if (curRole == "student") {
          baseRoutes = student_constantRoutes;
        } else {
          baseRoutes = constantRoutes;
          baseRoutes = [...baseRoutes, ...library_Routes]
        }
        // 向后端请求路由数据
        let res;
        if (curRole == "teacher" || curRole == "student" || curRole == "assistant") {
          res = {
            data: [],
          };
        } else {
          res = await getRouters();
        }
        console.log("curRole", curRole);
        const sdata = JSON.parse(JSON.stringify(res.data));
        const rdata = JSON.parse(JSON.stringify(res.data));
        const sidebarRoutes = filterAsyncRouter(sdata);
        const rewriteRoutes = filterAsyncRouter(rdata, false, true);
        const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
        rewriteRoutes.push({ path: "*", redirect: "/404", hidden: true });
        router.addRoutes(asyncRoutes);
        if (view && view.length > 0) {
          console.log(sidebarRoutes, baseRoutes);
          filtersRouters = changeSidebarRouters(
            view,
            baseRoutes.concat(sidebarRoutes)
          );
          filterAddRouters = changeSidebarRouters(view, rewriteRoutes);
          commit("SET_SIDEBAR_ROUTERS", filtersRouters);
          commit("SET_ROUTES", filterAddRouters);
        } else {
          commit("SET_SIDEBAR_ROUTERS", baseRoutes.concat(sidebarRoutes));
          commit("SET_ROUTES", rewriteRoutes);
        }
        commit("SET_DEFAULT_ROUTES", sidebarRoutes);
        commit("SET_TOPBAR_ROUTES", sidebarRoutes);
        resolve(filtersRouters ? filtersRouters : rewriteRoutes);
      });
    },
  },
};

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter((route) => {
    if (type && route.children) {
      route.children = filterChildren(route.children);
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === "Layout") {
        route.component = Layout;
      } else if (route.component === "ParentView") {
        route.component = ParentView;
      } else if (route.component === "InnerLink") {
        route.component = InnerLink;
      } else {
        route.component = loadView(route.component);
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type);
    } else {
      delete route["children"];
      delete route["redirect"];
    }
    return true;
  });
}

function filterChildren(childrenMap, lastRouter = false) {
  let children = [];
  childrenMap.forEach((el) => {
    if (el.children && el.children.length) {
      if (el.component === "ParentView" && !lastRouter) {
        el.children.forEach((c) => {
          c.path = el.path + "/" + c.path;
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c));
            return;
          }
          children.push(c);
        });
        return;
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + "/" + el.path;
    }
    children = children.concat(el);
  });
  return children;
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes) {
  const res = [];
  routes.forEach((route) => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route);
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route);
      }
    }
  });
  return res;
}

export const loadView = (view) => {
  return (resolve) => require([`@/views/${view}`], resolve);
};

export default permission;

//全局更改配置字段
function changeSidebarRouters(array, oldRoutes) {
  let sidebarRouters = oldRoutes;
  array.forEach((item) => {
    //全局设置$key，以实现全局动态改变某些字段
    let key = "$" + item.key;
    Vue.prototype[key] = item.newName;
    //遍历路由一级菜单
    for (const sidebarRouter of sidebarRouters) {
      //如果是 判断一级菜单有没有meta
      if (sidebarRouter.meta) {
        //有meta判断title里面是否包含label（需要更改的字段） 有的话用newName替换掉
        if (sidebarRouter.meta.title.indexOf(item.label) > -1) {
          sidebarRouter.meta.title = sidebarRouter.meta.title.replace(
            item.label,
            item.newName
          );
        }
      }
      //判断有没有二级菜单
      if (sidebarRouter.children && sidebarRouter.children.length > 0) {
        //有的话遍历二级菜单
        for (const childrenRouter of sidebarRouter.children) {
          // 判断二级菜单有没有meta
          if (childrenRouter.meta) {
            //有meta判断title里面是否包含label（需要更改的字段） 有的话用newName替换掉
            if (childrenRouter.meta.title.indexOf(item.label) > -1) {
              childrenRouter.meta.title = childrenRouter.meta.title.replace(
                item.label,
                item.newName
              );
            }
          }
          //判断有无三级菜单
          if (childrenRouter.children && childrenRouter.children.length > 0) {
            //遍历路由三级菜单
            for (const sonRouter of childrenRouter.children) {
              // 判断三级菜单有没有meta
              if (sonRouter.meta) {
                //有meta判断title里面是否包含label（需要更改的字段） 有的话用newName替换掉
                if (sonRouter.meta.title.indexOf(item.label) > -1) {
                  sonRouter.meta.title = sonRouter.meta.title.replace(
                    item.label,
                    item.newName
                  );
                }
              }
            }
          }
        }
      }
    }
  });
  return sidebarRouters;
}
